package com.crm.miaohe.app.service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.crm.miaohe.app.utils.WxUtil;
import com.crm.miaohe.mapper.TblUserOpenidMapper;
import com.crm.miaohe.mapper.TblXmapiResultMapper;
import com.crm.miaohe.model.TblUserOpenid;
import com.crm.miaohe.model.TblXmapiResult;
import com.wonder.common.utils.StringUtils;

import lombok.Getter;

@Service
public class WxService {

    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private static final String WX_TOKEN = "YC88888888yc";

    @Getter
    private static String AppId;
    @Value("${wx.appId}")
    public void setAppId(String appId) {
        AppId = appId;
    }
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private TblUserOpenidMapper tblUserOpenidMapper;
    
    @Autowired private TblXmapiResultMapper tblXmapiResultMapper;
    
    public Map<String,String> getOpenId(Map<String,Object> map) throws Exception { 
    	 String code = map.get("code").toString();
    	 String userid = map.get("userid").toString();
    	 String username = map.get("username").toString();
    	 String phonenum = map.get("phonenum").toString();
    	 Map datamap = WxUtil.getOpenId(code);
    	 Map<String,String> resMap = new HashMap<String,String>();
    	 String openid = null;
    	 if (datamap != null) {
    		 openid = (String) datamap.get("openid");
    		// 关联用户
        	 TblUserOpenid uoi = new TblUserOpenid();
        	 uoi.setUserId(Long.valueOf(userid));
        	 uoi.setUserName(username);
        	 uoi.setPhoneNumber(phonenum);
        	 uoi.setOpenId(openid);
        	 uoi.setAccessToken((String) datamap.get("access_token"));
        	 uoi.setRefreshToken((String) datamap.get("refresh_token"));
        	 uoi.setExpiresIn(datamap.get("expires_in").toString());
        	 uoi.setScope((String) datamap.get("scope"));
        	 tblUserOpenidMapper.insert(uoi);
        	
         }
    	 resMap.put("openid", openid);
         return resMap;
    }
    
    public String getAccessToken() {
        String accessToken = "";
        
        String json = WxUtil.getJSSDKAccessToken4WMApi();
        
        TblXmapiResult tokenapires = new TblXmapiResult();
    	tokenapires.setResmsg(json);
    	tblXmapiResultMapper.insert(tokenapires);
        
    	Map map = WxUtil.jsonToMap(json);
        if (map != null) {
        	accessToken = (String) map.get("access_token");
        }
    	return accessToken;
    }
    
    
    public Map sendMsg(String openid, String orderNo, String cusName, String status) {
    	String token = getAccessToken();
    	Map result = null;
    	if (!StringUtils.isEmpty(token) &&  !"null".equals(token)) {
    		JSONObject bodyParams = new JSONObject();
        	bodyParams.put("touser", openid);
        	
        	JSONObject params1 = new JSONObject();
        	params1.put("value", orderNo);
        	JSONObject params2 = new JSONObject();
        	params2.put("value", status);
        	JSONObject params3 = new JSONObject();
        	params3.put("value", cusName);
        	
        	JSONObject data = new JSONObject();
        	data.put("character_string2", params1);
        	data.put("phrase9", params2);
        	data.put("thing22", params3);
        	
        	bodyParams.put("data", data);
    		
    		result = WxUtil.sendMsg(token, bodyParams);
    		
        	TblXmapiResult napires = new TblXmapiResult();
        	napires.setResmsg(WxUtil.mapToJson(result));
        	tblXmapiResultMapper.insert(napires);
    	}
    	
    	
    	return result;
    }
    
    /**
     *@Author: hdx
     *@CreateTime: 20:46 2020/2/14
     *@param:  shareUrl 分享的url
     *@Description: 初始化JSSDKConfig
     */
    public Map<String,String> initJSSDKConfig(String url) throws Exception {
        //获取AccessToken
        //先从缓存中获取
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String accessToken = String.valueOf(valueOperations.get("accessToken"));
        //如果缓存中没有的话再去url获取
        if(StringUtils.isEmpty(accessToken) || "null".equals(accessToken)){
            accessToken = WxUtil.getJSSDKAccessToken();
        }
        //String accessToken = WxUtil.getJSSDKAccessToken();
        //获取JssdkGetticket
        //先从缓存中获取
        String jsapiTicket = String.valueOf(valueOperations.get("jsapiTicket"));
        if(StringUtils.isEmpty(jsapiTicket) || "null".equals(jsapiTicket)){
            jsapiTicket = WxUtil.getJssdkGetticket(accessToken);
        }
        //String jsapiTicket = WxUtil.getJssdkGetticket(accessToken);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String nonceStr = UUID.randomUUID().toString();
        String signature = WxUtil.buildJSSDKSignature(jsapiTicket,timestamp,nonceStr,url);
        Map<String,String> map = new HashMap<String,String>();
        map.put("url", url);
        map.put("jsapi_ticket", jsapiTicket);
        map.put("nonceStr", nonceStr);
        map.put("timestamp", timestamp);
        map.put("signature", signature);
        map.put("appid", AppId);
        map.put("accessToken", accessToken);
        //accessToken存到redis中
        valueOperations.set("accessToken",accessToken,7200, TimeUnit.SECONDS);
        valueOperations.set("jsapiTicket",jsapiTicket,7200, TimeUnit.SECONDS);
        return map;
    }

    public boolean checkSignature(String signature, String timestamp, String nonce) {
        String checktext = null;
        if (null != signature) {
            //对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[]{WX_TOKEN,timestamp,nonce};
            Arrays.sort(paramArr);
            //将排序后的结果拼成一个字符串
            String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                //对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());
                checktext = byteToStr(digest);
            } catch (NoSuchAlgorithmException e){
                e.printStackTrace();
            }
        }
        //将加密后的字符串与signature进行对比
        return checktext !=null ? checktext.equals(signature.toUpperCase()) : false;

    }

    /**
     *  将字节转化为十六进制字符串
     * @param myByte 字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }

    /**
     * 将字节数组转化我16进制字符串
     * @param byteArrays 字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays){
        char[] buf = new char[byteArrays.length * 2];
        int index = 0;
        for (byte b : byteArrays){
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }
        return new String(buf);
    }
}
